package com.billard.service.impl;


import com.billard.dto.LoginDTO;
import com.billard.dto.UserWithRoleDTO;
import com.billard.result.PageResult;
import com.billard.Query.UserQuery;
import com.billard.entity.User;
import com.billard.exception.AccountNotFoundException;
import com.billard.exception.MessageConstant;
import com.billard.mapper.UserMapper;
import com.billard.mapper.RoleMapper;
import com.billard.properties.JwtProperties;
import com.billard.service.UserService;
import com.billard.utils.BCryptUtil;
import com.billard.utils.JwtUtil;
import com.billard.utils.RedisUtil;
import com.billard.utils.UserIdUtil;
import com.billard.vo.LoginVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 用户服务实现类
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private BCryptUtil bCryptUtil;
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private RedisUtil redisUtil;


    @Override
    public LoginVO login(LoginDTO loginDTO) {
        String key = "user:" + loginDTO.getUsername()+loginDTO.getPassword();
        LoginVO redisData = null;
        try {
            redisData = redisUtil.get(key, LoginVO.class);
        } catch (Exception e) {
            log.error("Redis 未连接");
        }
        if (redisData != null) {
            log.info("从 Redis 中获取用户信息成功");
            return redisData;
        }
        LoginVO loginVO = UserDate(key,loginDTO);

        return loginVO;
    }
    /**
     * 用户登录逻辑
     */
    public LoginVO UserDate(String key,LoginDTO loginDTO){
        //  查询用户 + 角色
        User user = userMapper.selectUserWithRolesByUsername(loginDTO.getUsername());
        if (user == null) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        log.warn("用户信息: {}", user);
        if (!bCryptUtil.checkPassword(loginDTO.getPassword(), user.getPassword())) {
            throw new AccountNotFoundException(MessageConstant.PASSWORD_ERROR);//admin123，111111
        }

        if (user.getStatus() == 0) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_LOCKED);
        }

        Map<String, Object> claim = new HashMap<>();
        claim.put("username", user.getUsername());
        claim.put("id", user.getId());

        String token = JwtUtil.create_Jwt(jwtProperties.getSecretKey(), jwtProperties.getTtlMills(), claim);

        // 查询权限
        List<String> permissions = userMapper.selectPermissionsByUserId(user.getId());

        LoginVO loginVO = new LoginVO();
        BeanUtils.copyProperties(user, loginVO);
        loginVO.setUserId(user.getId());
        loginVO.setToken(token);
        loginVO.setPermissions(permissions);
        // 角色信息已通过 User.role 自动复制到 loginVO
        loginVO.setRole(user.getRole());
        // 缓存到 Redis
        redisUtil.set(key, loginVO, jwtProperties.getTtlMills());
        log.info("缓存用户信息到 Redis: {}", key);
        return loginVO;
    }



    @Override
    public User getUserById(Long id) {
        // 获取当前操作员ID
        Long currentUserId = UserIdUtil.getUserId();
        if (currentUserId != null) {
            // 可以记录操作日志
            System.out.println("查询用户信息操作员ID: " + currentUserId);
        }

        return userMapper.selectById(id);
    }

    @Override
    public User getUserByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    public void createUser(User user) {
        // 获取当前操作员ID
        Long currentUserId = UserIdUtil.getUserId();
        if (currentUserId != null) {
            // 可以记录操作日志
            System.out.println("创建用户操作员ID: " + currentUserId);
        }

        // 检查用户名是否已存在
        User existingUser = userMapper.selectByUsername(user.getUsername());
        if (existingUser != null) {
            throw new AccountNotFoundException(MessageConstant.ALREADY_EXISTS);
        }
        // 加密密码
        user.setPassword(bCryptUtil.encryptPassword(user.getPassword()));

        // 插入用户
        userMapper.insert(user);

        // 为用户分配角色
        Long roleId = 5L; // 默认角色ID=5（客户）

        // 检查并处理角色信息
        if (user.getRole() != null && !user.getRole().isEmpty()) {
            // 方法1：如果role对象中有id，则直接使用
            if (user.getRole().get(0).getId() != null) {
                roleId = user.getRole().get(0).getId();
            }
            // 方法2：如果role对象中有code，则根据code查找roleId
            else if (user.getRole().get(0).getCode() != null) {
                // 这里假设需要实现一个根据code查询角色的方法
                // roleId = getRoleIdByCode(user.getRole().get(0).getCode());
                // 或者简单映射：
                String roleCode = user.getRole().get(0).getCode();
                if ("ADMIN".equals(roleCode)) roleId = 1L;
                else if ("WAITER".equals(roleCode)) roleId = 2L;
                else if ("FINANCE".equals(roleCode)) roleId = 3L;
                else if ("CUSTOMER".equals(roleCode)) roleId = 5L;
            }
        }

        // 分配角色
        assignRoleToUser(user.getId(), roleId);
    }

    @Override
    public void updateUser(User user) {
        // 获取当前操作员ID
        Long currentUserId = UserIdUtil.getUserId();
        if (currentUserId != null) {
            // 可以记录操作日志
            System.out.println("更新用户操作员ID: " + currentUserId);
        }

        userMapper.updateById(user);
    }

    @Override
    public void deleteUser(Long id) {
        // 获取当前操作员ID
        Long currentUserId = UserIdUtil.getUserId();
        if (currentUserId != null) {
            // 可以记录操作日志
            System.out.println("删除用户操作员ID: " + currentUserId);
        }
        userMapper.deleteById(id);
    }

    @Override
    public PageResult page(UserQuery query) {
        // 获取当前操作员ID
        Long currentUserId = UserIdUtil.getUserId();
        if (currentUserId != null) {
            // 可以记录操作日志
            System.out.println("用户分页查询操作员ID: " + currentUserId);
        }

        // 查询列表和总数
        List<UserWithRoleDTO> users = userMapper.selectByQuery(query);
        // 分页结果
        long total = userMapper.countByQuery(query);
        return new PageResult(total, users);
    }

    @Override
    public void updatePassword(Long id, String oldPassword, String newPassword) {
        // 获取当前操作员ID
        Long currentUserId = UserIdUtil.getUserId();
        if (currentUserId != null) {
            // 可以记录操作日志
            System.out.println("修改密码操作员ID: " + currentUserId);
        }
        User db = userMapper.selectById(id);
        if (db == null) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        // 校验旧密码
        if (!bCryptUtil.checkPassword(oldPassword, db.getPassword())) {
            throw new AccountNotFoundException(MessageConstant.PASSWORD_ERROR);
        }
        // 加密新密码并更新
        String encrypted = bCryptUtil.encryptPassword(newPassword);
        userMapper.updatePassword(id, encrypted);
        // 清除缓存：避免旧token携带旧信息（可选）
        String key = "user:" + db.getUsername()+db.getPassword();
        redisUtil.delete(key);
        log.info("清除缓存成功: {}", key);
    }

    @Override
    public void assignRoleToUser(Long userId, Long roleId) {
        userMapper.insertUserRole(userId, roleId);
    }
}
